package com.ruoyi.system.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.enums.VideoParseResponse;
import com.ruoyi.common.utils.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 快手短视频解析服务
 * @Author: JH-Ahua
 * @CreateTime: 2025/1/15
 */
@Service
public class KuaishouService {
    
    private static final Logger logger = LoggerFactory.getLogger(KuaishouService.class);
    
    /**
     * 解析快手视频
     * @param url 快手分享链接
     * @return 解析结果
     */
    public VideoParseResponse parseKuaishouVideo(String url) {
        try {
            // 验证URL
            if (url == null || url.trim().isEmpty()) {
                return new VideoParseResponse(201, "链接不能为空！", null);
            }
            
            // 解析快手视频
            VideoParseResponse.VideoData data = kuaishou(url);
            if (data != null) {
                return new VideoParseResponse(200, "解析成功", data);
            } else {
                return new VideoParseResponse(404, "链接错误", null);
            }
            
        } catch (Exception e) {
            logger.error("解析快手视频失败", e);
            return new VideoParseResponse(500, "解析失败: " + e.getMessage(), null);
        }
    }
    
    /**
     * 快手视频解析核心方法
     * @param url 快手分享链接
     * @return 解析结果数据
     */
    private VideoParseResponse.VideoData kuaishou(String url) {
        try {
            // 构造请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Cookie", "");
            headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0");
            
            // 获取重定向后的URL
            String newUrl = getRedirectedUrl(url, headers);
            String response = "";
            String videoType = "";
            String id = "";
            
            // 匹配不同类型的视频链接
            Pattern shortVideoPattern = Pattern.compile("/short-video/([^?]+)");
            Pattern photoPattern = Pattern.compile("/photo/([^?]+)");
            Pattern longVideoPattern = Pattern.compile("/long-video/([^?]+)");
            
            Matcher shortVideoMatcher = shortVideoPattern.matcher(newUrl);
            Matcher photoMatcher = photoPattern.matcher(newUrl);
            Matcher longVideoMatcher = longVideoPattern.matcher(newUrl);
            
            if (shortVideoMatcher.find()) {
                videoType = "short-video";
                id = shortVideoMatcher.group(1);
                response = httpGet(url, headers);
                while (response == null) {
                    response = httpGet(url, headers);
                }
            } else if (longVideoMatcher.find()) {
                videoType = "long-video";
                id = longVideoMatcher.group(1);
                String requestUrl = "https://www.kuaishou.com/short-video/" + id;
                response = httpGet(requestUrl, headers);
                while (response == null) {
                    response = httpGet(requestUrl, headers);
                }
            } else if (photoMatcher.find()) {
                videoType = "photo";
                id = photoMatcher.group(1);
                String requestUrl = "https://www.kuaishou.com/short-video/" + id;
                response = httpGet(requestUrl, headers);
                while (response == null) {
                    response = httpGet(requestUrl, headers);
                }
            }
            
            if (response == null || response.isEmpty()) {
                response = httpGet(url, headers);
            }
            
            if (response != null && !response.isEmpty()) {
                return parseApolloState(response, id, videoType);
            }
            
            return null;
            
        } catch (Exception e) {
            logger.error("快手视频解析失败", e);
            return null;
        }
    }
    
    /**
     * 获取重定向后的URL
     * @param url 原始URL
     * @param headers 请求头
     * @return 重定向后的URL
     */
    private String getRedirectedUrl(String url, Map<String, String> headers) {
        try {
            return HttpUtils.getFinalUrl(url, headers);
        } catch (Exception e) {
            logger.error("获取重定向URL失败", e);
            return url;
        }
    }
    
    /**
     * 发送HTTP GET请求
     * @param url 请求URL
     * @param headers 请求头
     * @return 响应内容
     */
    private String httpGet(String url, Map<String, String> headers) {
        try {
            return HttpUtils.get(url, headers);
        } catch (Exception e) {
            logger.error("HTTP GET请求失败", e);
            return null;
        }
    }
    
    /**
     * 解析Apollo State数据
     * @param response HTML响应内容
     * @param id 视频ID
     * @param videoType 视频类型
     * @return 解析结果数据
     */
    private VideoParseResponse.VideoData parseApolloState(String response, String id, String videoType) {
        try {
            // 匹配window.__APOLLO_STATE__
            Pattern apolloStatePattern = Pattern.compile("window\\.__APOLLO_STATE__\\s*=\\s*(.*?)</script>", Pattern.DOTALL);
            Matcher matcher = apolloStatePattern.matcher(response);
            
            if (matcher.find()) {
                String apolloStateStr = matcher.group(1);
                
                // 清理Apollo State字符串
                String cleanedApolloState = cleanApolloState(apolloStateStr);
                
                // 解析JSON
                JSONObject apolloState = JSONObject.parseObject(cleanedApolloState);
                JSONObject videoInfo = apolloState.getJSONObject("defaultClient");
                
                if (videoInfo != null) {
                    String key = "VisionVideoDetailPhoto:" + id;
                    JSONObject json = videoInfo.getJSONObject(key);
                    
                    if (json != null) {
                        String videoUrl = "";
                        
                        if ("long-video".equals(videoType)) {
                            // 长视频处理
                            JSONObject manifestH265 = json.getJSONObject("manifestH265");
                            if (manifestH265 != null) {
                                JSONObject manifestJson = manifestH265.getJSONObject("json");
                                if (manifestJson != null) {
                                    JSONObject adaptationSet = manifestJson.getJSONArray("adaptationSet").getJSONObject(0);
                                    if (adaptationSet != null) {
                                        JSONObject representation = adaptationSet.getJSONArray("representation").getJSONObject(0);
                                        if (representation != null) {
                                            videoUrl = representation.getJSONArray("backupUrl").getString(0);
                                        }
                                    }
                                }
                            }
                        } else {
                            // 短视频和图片处理
                            videoUrl = json.getString("photoUrl");
                        }
                        
                        if (videoUrl != null && !videoUrl.isEmpty()) {
                            VideoParseResponse.VideoData data = new VideoParseResponse.VideoData();
                            data.setTitle(json.getString("caption"));
                            data.setCover(json.getString("coverUrl"));
                            data.setUrl(videoUrl);
                            data.setApi(1);
                            
                            // 设置统一结构的默认值
                            data.setAuthor("快手用户");
                            data.setUid("");
                            data.setAvatar("");
                            data.setLike(0L);
                            data.setTime(System.currentTimeMillis());
                            data.setImages("快手视频解析");
                            data.setMusic("快手视频原声");
                            
                            return data;
                        }
                    }
                }
            }
            
            return null;
            
        } catch (Exception e) {
            logger.error("解析Apollo State失败", e);
            return null;
        }
    }
    
    /**
     * 清理Apollo State字符串
     * @param apolloStateStr 原始Apollo State字符串
     * @return 清理后的字符串
     */
    private String cleanApolloState(String apolloStateStr) {
        try {
            // 移除函数定义
            Pattern functionPattern = Pattern.compile("function\\s*\\([^)]*\\)\\s*\\{[^}]*\\}");
            String cleaned = functionPattern.matcher(apolloStateStr).replaceAll(":");
            
            // 移除多余的逗号
            cleaned = cleaned.replaceAll(",\\s*(?=[}\\]])", "");
            
            // 移除特定字符链
            cleaned = cleaned.replace(";(:());", "");
            
            return cleaned;
        } catch (Exception e) {
            logger.error("清理Apollo State字符串失败", e);
            return apolloStateStr;
        }
    }
}
